# -*- coding: utf-8 -*-
#
# Copyright (c) 2012, Rafael Pivato
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Rafael Pivato nor the names of its contributors
#       may be used to endorse or promote products derived from this
#       software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL RAFAEL PIVATO BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import urllib2
from bcoma import BcomaFormatError
from bcoma import download_filtered_lines
from bcoma import create_api_uri
from bcoma import download_json


class Auction(object):
    """Helps accessing Auction House data."""

    def __init__(self, data):
        try:
            self.id = data['auc']
            self.item = data['item']
            self.owner = data['owner']
            self.bid = data['bid']
            self.buyout = data['buyout']
            self.quantity = data['quantity']
            self.time_left = data['timeLeft']
        except KeyError as missing_key:
            detail = 'Missing Auction JSON key %s.' % (missing_key)
            raise BcomaFormatError('unknown', missing_key, detail)


class AuctionFile(object):
    """Handles Auction file data."""

    def __init__(self, data):
        try:
            self.url = data['url']
            self.last_modified = data['lastModified']
            self.data = None
        except KeyError as missing_key:
            detail = 'Missing AuctionFile JSON key %s.' % (missing_key)
            raise BcomaFormatError('unknown', missing_key, detail)

    def download_data(self, filter_func):
        """Downloads this auction file."""
        self.data = download_filtered_lines(self.url, filter_func)
        return self.data

    def deprecated_filter_auctions(self, side, item):
        """Filters to return only auctions for a given item."""
        faction = 'alliance'
        if side == 1:
            faction = 'horde'
        auctions = []
        try:
            auctions_data = self.data[faction]['auctions']
            for auction_data in auctions_data:
                if auction_data['item'] == item:
                    auctions.append(Auction(auction_data))
        except KeyError as missing_key:
            detail = 'Missing JSON key %s while filtering auction.' % \
                (missing_key)
            raise BcomaFormatError('unknown', missing_key, detail)
        else:
            return auctions

    @classmethod
    def fetch(cls, realm):
        realm = urllib2.quote(realm)
        path = 'auction/data/%s' % (realm)
        uri = create_api_uri(path)
        data = download_json(uri)
        if 'status' in data and data['status'] == 'nok':
            return None
        if 'files' in data:
            json_files = data['files']
            files = []
            try:
                for json_file in json_files:
                    files.append(AuctionFile(json_file))
            except BcomaFormatError as format_error:
                format_error.uri = uri
                raise format_error
            else:
                return files

    @classmethod
    def fetch_newest(cls, realm):
        files = cls.fetch(realm)
        if files is None:
            return files
        files = sorted(files, key=lambda i: i.last_modified)
        return files[-1]
